import cn from 'classnames';
import PropTypes from 'prop-types';
import React, { useEffect, useMemo, useState, useRef } from 'react';
import moment from 'moment';
import { withRouter } from 'react-router';
import Table from '@knownsec/react-component/dist/Table';
import { Link } from 'react-router-dom';
import fetchFer from 'API/fetch';
import Pagination from '@knownsec/react-component/dist/Pagination';
import Dialog from '@knownsec/react-component/dist/Dialog';
import EmptyData from '../../../../components/empty/EmptyData';
import {
	GetQueryString,
	turnToUrlparam,
} from '../../../../helpers/getUrlParams';
import { cloneDeep } from 'lodash';
import { datetime } from '../../../../../common/formatter';
import { filterNull } from '../../../../../common/validation/common';
import s from './style.module.css';
import Button from '@kuiper-components/button';
import Input from '@kuiper-components/input';
import Select, { Option } from '@kuiper-components/select';
import EventCount from './EventCount';
import CheckAlert from './CheckAlert';
import { Progress, Menu, Dropdown } from 'antd';
import notification from '@kuiper-components/notification';
import confirm from '../../../../components/confirm';
import Message from '@knownsec/react-component/dist/Message';
// import Progress from '@knownsec/react-component/dist/Progress';

import {
	Search24 as SearchIcon,
	ChevronDown16 as ChevronDown,
} from '@carbon/icons-react';
import CopyBoard from '../../../../components/CopyBoard';

import Switch from '@kuiper-components/switch';
import Tooltip from '@kuiper-components/tooltip';
const taskType = { schedule: '周期任务', manual: '单次任务' };
const monitorStatus = {
	waiting: '等待调度',
	active: '正在检测',
	completed: '检测完成',
	failed: '检测失败',
	stopped: '检测停止',
	// unkonwn: '未知',
};
const defaultFilter = {
	page: 1,
	count: 10,
	task_group_type: 'host',
};
function TaskTable({
	match: {
		params: { assetType },
	},
	history,
	location,
	setRefresh,
}) {
	const resD = JSON.parse(sessionStorage.getItem('resD')) || {};
	const isPlanTimeOut =
		moment().unix() > moment(sessionStorage.planTimeOut).unix();
	const target_url = GetQueryString(location.search, 'target_url');
	const prefilter = new URLSearchParams(location.search).get('filter');
	const filterS = prefilter ? JSON.parse(prefilter) || {} : {};
	const defaultFilter_ = { ...defaultFilter, ...filterS };
	const [filter, setFilter] = React.useState(defaultFilter_);
	const [tableData, setTableData] = React.useState({ data: [], count: 0 });
	const [selectedRows, setSelectedRows] = React.useState([]);
	const [sendData, setSendData] = React.useState();
	const [loading, setLoading] = React.useState(false);

	const columns = [
		{
			title: '任务名称',
			key: 'name',
			dataIndex: 'name',
			render(val) {
				return <CopyBoard className={s.affect} text={val} />;
			},
		},
		{
			title: '资产地址',
			key: 'target_url',
			dataIndex: 'target_url',
			render(val) {
				return <CopyBoard className={s.affect} text={val} />;
			},
		},
		{
			title: '监测开始时间',
			key: 'start_time',
			dataIndex: 'start_time',
			render(e, row) {
				return (
					<Tooltip
						placement="top"
						overlay={
							row.enable_monitor ? (
								<span>下一次监测时间: {datetime(row.next_time) || '- -'}</span>
							) : (
								'该监测任务已关闭'
							)
						}
					>
						<span>{datetime(e) || '- -'}</span>
					</Tooltip>
				);
			},
		},
		{
			title: '任务类型',
			key: 'trigger_type',
			dataIndex: 'trigger_type',
			width: 70,
			render(e) {
				return <span>{taskType[e]}</span>;
			},
		},
		{
			title: '监测状态',
			key: 'detail',
			dataIndex: 'detail',
			width: 140,
			render(e, row) {
				return (
					<div>
						<span className={cn(s.dotSpan, s[e?.process?.status])}></span>
						<span
							className={s.circle}
							onClick={
								e?.process?.status === 'unknown'
									? null
									: () => progressDetail(row)
							}
						>
							{monitorStatus[e?.process?.status]}
						</span>
						{/* {e?.process?.status !== 'unkonwn' && (
							<>
								<Progress
									percent={e?.process?.progress || 0}
									showInfo={false}
									className={s.Progress}
									strokeColor={'#0b73da'}
								/>
								<span className={s.circle}>{e?.process?.progress}%</span>
							</>
						)} */}
					</div>
				);
			},
		},
		{
			title: '最近一次监测结果',
			key: 'detail2',
			dataIndex: 'detail',
			width: 240,
			render(e, row) {
				return <EventCount className={s.lh1} row={row} />;
			},
		},
		{
			title: '监测开关',
			key: 'enable_monitor',
			dataIndex: 'enable_monitor',
			width: 70,
			render(e, row) {
				const enableMonitor = row.enable_monitor;
				const id = row.asset_task_id;
				const type = row.trigger_type;
				return (
					<>
						{type === 'schedule' ? (
							<Switch
								checked={enableMonitor}
								defaultChecked={enableMonitor}
								onChange={checked => {
									changeSwitch(checked, id);
								}}
							/>
						) : (
							'- -'
						)}
					</>
				);
			},
		},
		{
			title: '操作',
			key: 'enable_monitor2',
			dataIndex: 'enable_monitor',
			width: 150,
			render(x, row) {
				const id = row.asset_task_id;
				const tid = row.task_id;
				const jid = row.job_id;
				const type = row.trigger_type;
				const rid = row.result_id;
				const monitorType = ['waiting', 'active'];
				return (
					<div className={s.controlContainer}>
						<div className={s.control}>
							{rid && (
								<Link
									className={s.item}
									to={{
										pathname: `/job-manage/host-task/detail`,
										search: `jid=${jid}&tid=${tid}&id=${id}&type=${type}`,
									}}
								>
									监测结果
								</Link>
							)}
							<Dropdown
								// visible={true}
								overlay={
									<Menu>
										{type === 'schedule' && (
											<Menu.Item key="1">
												<Link
													className={s.itemSpan}
													to={{
														pathname: '/job-manage/create-job-all',
														search: `assetType=host&atid=${id}`,
													}}
												>
													任务配置
												</Link>
											</Menu.Item>
										)}
										{type === 'manual' &&
											monitorType.includes(row.detail.process?.status) && (
												<Menu.Item key="2">
													<span
														className={s.itemSpan}
														onClick={() => {
															stopTask([tid]);
														}}
													>
														停止
													</span>
												</Menu.Item>
											)}
										<Menu.Item key="3">
											<span
												className={s.itemSpan}
												onClick={e => {
													handleDelete([id]);
												}}
											>
												删除
											</span>
										</Menu.Item>
										{type === 'manual' &&
											row.detail.process?.status === 'stopped' && (
												<Menu.Item key="4">
													<span
														className={s.itemSpan}
														onClick={() => {
															repeatTask([tid]);
														}}
													>
														重试
													</span>
												</Menu.Item>
											)}
									</Menu>
								}
								trigger={['click']}
								getPopupContainer={triggerNode => triggerNode.parentElement}
							>
								<a className={s.dropdown} onClick={e => e.preventDefault()}>
									管理
									<ChevronDown />
								</a>
							</Dropdown>
						</div>
					</div>
				);
			},
		},
	];
	/// /////////////////////////////
	const repeatTask = async ids => {
		const res = await fetchFer(` /api/v2/tasks/retry`, {
			method: 'POST',
			body: JSON.stringify({ ids }),
			checkStatus: 501,
		});
		if (res.msg === 'ok') {
			notification.success({
				placement: 'top',
				message: res.message || `操作成功`,
			});
			getData();
		} else {
			notification.error({
				message: res.msg || res.message,
				placement: 'top',
			});
		}
	};
	const stopTask = async ids => {
		const res = await fetchFer(`/api/v2/tasks/stop`, {
			method: 'POST',
			checkStatus: 501,
			body: JSON.stringify({ ids }),
		});
		if (res.msg === 'ok') {
			notification.success({
				placement: 'top',
				message: `操作成功`,
			});
			setRefresh(Math.random().toString(36).slice(-6));
			getData();
		} else {
			notification.error({
				message: '操作失败',
				placement: 'top',
			});
		}
	};
	const changeSwitch = async (e, id) => {
		const change = async () => {
			ergodic();
			setLoading(true);
			const params = {
				asset_task_id: id,
				enable_monitor: e,
			};
			const res = await fetchFer(`/api/v2/jobs/host_vul_task_switch`, {
				method: 'POST',
				body: JSON.stringify(params),
				checkStatus: 501,
			}).catch(err => {
				return err;
			});
			if (res.code !== 0) {
				notification.error({
					message: res.msg,
					placement: 'top',
				});
				setRefresh(Math.random().toString(36).slice(-6));
				e && getData();
				ergodic();
			} else {
				notification.success({
					message: '修改成功',
					placement: 'top',
				});
			}
			setLoading(false);
		};
		const ergodic = () => {
			const tableData_ = tableData.data.map(item => {
				if (item.asset_task_id === id) {
					item.enable_monitor = !item.enable_monitor;
				}
				return item;
			});
			setTableData({ ...tableData, data: tableData_ });
		};
		if (!e) {
			confirm.warning({
				message: `你确定要关闭该监测任务吗？该操作将在下一周期生效。`,
				okText: '确定',
				cancelText: '取消',
				title: '',
				onOk: async () => {
					change();
				},
			});
		} else {
			change();
		}
	};
	const handleChangeSearch = e => {
		let filter_ = null;
		if (e && e.page) {
			filter_ = { ...filter, ...e };
		} else {
			filter_ =
				e === 'r' ? defaultFilter : { ...filter, ...e, page: 1, count: 10 };
		}
		const backparams = JSON.stringify(filter_);
		const searchString = 'filter=' + encodeURI(backparams);
		history.replace(`/job-manage/host-task?${searchString}`);
		setFilter(filter_);
		getData(filter_, e);
	};
	const onSelectChange = newSelectedRowKeys => {
		setSelectedRows(newSelectedRowKeys);
	};
	const changeShow = () => {
		setSendData(null);
	};
	const handleDelete = id => {
		const asset_task_ids = id || selectedRows;
		confirm.warning({
			message: `确认删除选择的任务？`,
			okText: '删除',
			cancelText: '取消',
			title: '',
			onCancel: () => {
				setSelectedRows([]);
			},
			onOk: async () => {
				const res = await fetchFer(`/api/v2/jobs/host_vul_task_delete`, {
					method: 'POST',
					body: JSON.stringify({ asset_task_ids }),
				});
				if (res.code === 0) {
					notification.success({
						placement: 'top',
						message: `删除成功`,
					});
					setRefresh(Math.random().toString(36).slice(-6));
					getData();
				} else {
					notification.error({
						message: '删除失败',
						placement: 'top',
					});
				}
				setSelectedRows([]);
			},
		});
	};
	const getData = async (e, f) => {
		setLoading(true);
		const sendData = f === 'r' ? e : { ...filter, ...e };
		const params = turnToUrlparam(sendData);
		const res = await fetchFer(`/api/v2/jobs/host_vul_task_list?${params}`, {
			method: 'GET',
			checkStatus: 501,
		}).catch(e => {
			return {};
		});
		if (res.data.asset_task_list.length < 1 && sendData.page > 1) {
			setFilter({ ...filter, limit: 10, page: sendData.page - 1 });
			getData({ limit: 10, page: sendData.page - 1 });
			return false;
		}
		if (res.code === 0) {
			if (res.data.asset_task_list) {
				const data = res.data.asset_task_list.map(e => {
					e.id = e.asset_task_id;
					e.key = e.asset_task_id;
					return e;
				});
				setTableData({
					data,
					count: res.data.total,
				});
			}
		}
		setLoading(false);
	};
	const [dialogVisible, setDialogVisible] = useState(false);
	const [chooseTaskStatus, setChooseTaskStatus] = useState('');
	const [chooseTaskTriggerType, setChooseTaskTriggerType] =
		useState('schedule');
	const [progressData, setProgressData] = React.useState([]);
	const timer = useRef();
	const searchProgress = row => {
		if (timer.current) clearInterval(timer.current);
		const task = cloneDeep(row);
		const isSearch = task.detail.process.progress < 100;
		setChooseTaskStatus(task.detail.process.status);
		setChooseTaskTriggerType(task.trigger_type);
		if (
			isSearch &&
			(task.detail.process.status === 'active' ||
				task.detail.process.status === 'waiting')
		) {
			timer.current = setInterval(function () {
				fetchFer(
					`/api/v2/tasks/host/status?asset_task_id=${task.asset_task_id}`,
					{
						method: 'GET',
					}
				).then(res => {
					if (res.code === 200) {
						setProgressData([
							{
								taskName: '主机安全监测',
								progress: res.data.host_vul.progress,
								status: res.data.host_vul.status,
								...task,
							},
						]);
						if (res.data.host_vul.progress === 100) {
							clearInterval(timer.current);
						}
					}
				});
			}, 3000);
		}
	};
	const progressDetail = row => {
		searchProgress(row);
		setChooseTaskTriggerType(row.trigger_type);
		setProgressData([
			{ taskName: '主机安全监测', ...row.detail.process, ...row },
		]);
		setDialogVisible(true);
	};
	useMemo(() => {
		if (target_url) {
			setFilter({ ...filter, target_url });
		}
	}, []);
	useEffect(() => {
		getData();
		return () => {
			if (timer.current) clearInterval(timer.current);
		};
	}, []);
	return (
		<div className={s.content}>
			<Button
				primary={true}
				onClick={
					isPlanTimeOut ||
					(!resD?.feature?.hostVulTask && !resD?.feature?.hostVulManualTask)
						? () => {
								return Message.show({
									type: 'error',
									message: '请先升级套餐服务',
								});
						  }
						: () =>
								(window.location.href = `/#/job-manage/create-job-all?assetType=host`)
				}
			>
				新建监测任务
			</Button>
			<div className={s.search}>
				<Input
					onChange={target_url => {
						setFilter({ ...filter, target_url });
					}}
					className={s.input}
					placeholder="请输入资产地址"
					after={
						<SearchIcon
							className={s.icon}
							onClick={() => {
								handleChangeSearch();
							}}
						/>
					}
					value={filter.target_url}
					onPressEnter={() => {
						handleChangeSearch();
					}}
					type="search"
				/>
				<div className={s.selectContainer}>
					<Select
						placeholder="任务类型"
						className={s.item}
						value={filter.trigger_type}
						allowClear={true}
						getPopupContainer={triggerNode => triggerNode}
						onChange={trigger_type => {
							handleChangeSearch({ trigger_type });
						}}
					>
						<Option value="schedule">周期任务</Option>
						<Option value="manual">单次任务</Option>
					</Select>
					<Select
						placeholder="监测结果"
						className={s.item}
						value={filter.level}
						allowClear={true}
						getPopupContainer={triggerNode => triggerNode}
						onChange={level => {
							console.log(level);
							handleChangeSearch({ level });
						}}
					>
						<Option value="严重">严重</Option>
						<Option value="高危">高危</Option>
						<Option value="中危">中危</Option>
						<Option value="低危">低危</Option>
						<Option value="安全">安全</Option>
						<Option value="未知">未知</Option>
					</Select>
					<Select
						placeholder="监测状态"
						className={s.item}
						value={filter.status}
						allowClear={true}
						getPopupContainer={triggerNode => triggerNode}
						onChange={status => {
							handleChangeSearch({ status });
						}}
					>
						{Object.keys(monitorStatus).map(e => {
							return (
								<Option value={e} key={e}>
									{monitorStatus[e]}
								</Option>
							);
						})}
					</Select>

					<Button
						className={s.btn}
						onClick={() => {
							// setFilter(defaultFilter);
							handleChangeSearch('r');
						}}
					>
						重置
					</Button>
				</div>
			</div>
			<div className={s.tableContainer}>
				<Table
					rowSelection={{
						selectedRowKeys: selectedRows,
						onChange: onSelectChange,
					}}
					key={Date.now()}
					columns={columns}
					data={tableData.data}
					pro
					loading={loading}
					empty={<EmptyData className={s.nobor} />}
				/>
				<div className={s.secondRow}>
					<div className={s.lineBtn}>
						<Button
							link
							disabled={!selectedRows.length}
							className={{ [s.highLight]: selectedRows.length }}
							onClick={() => {
								handleDelete();
							}}
						>
							批量删除
						</Button>
					</div>
					{tableData.count > 10 && (
						<Pagination
							current={filter.page || 1}
							pageSize={filter.count || 10}
							pageSizeOptions={[10, 20, 50]}
							showSizeChanger
							showQuickJumper
							showTotal={total => `共${total}条`}
							total={tableData.count}
							onChange={(page, count) => {
								handleChangeSearch({ page, count });
							}}
						/>
					)}
				</div>
			</div>
			<CheckAlert data={sendData} type={0} changeShow={changeShow}></CheckAlert>
			<Dialog
				visible={dialogVisible}
				className={cn(s.dialog, {
					[s.w800]: chooseTaskTriggerType === 'schedule',
				})}
				title="进度详情"
				confirmText=""
				cancelText="关闭"
				onhide={() => {
					if (timer.current) clearInterval(timer.current);
					setDialogVisible(false);
					if (chooseTaskStatus === 'active' || chooseTaskStatus === 'waiting') {
						getData();
					}
				}}
			>
				<div className={s.p20}>
					<Table
						className={s.maxWunset}
						key={chooseTaskTriggerType}
						columns={[
							{
								title: '监测项',
								key: 'taskName',
								dataIndex: 'taskName',
							},
							{
								title: '检测开始时间',
								key: 'start_time',
								dataIndex: 'start_time',
								render(e, row) {
									return (
										<span>
											{moment(e).format('YYYY-MM-DD HH:mm:ss') || '- -'}
										</span>
									);
								},
							},
							{
								title: '检测进度',
								key: 'detail',
								dataIndex: 'detail',
								width: 280,
								render(e, row) {
									return (
										<div>
											<span className={s.circle}>
												{monitorStatus[row.status]}
											</span>
											{row.status !== 'unkonwn' && (
												<>
													<Progress
														percent={row.progress || 0}
														showInfo={false}
														className={s.Progress}
														strokeColor={
															row.status === 'stopped' ? '#D9D9D9' : '#0b73da'
														}
													/>
													<span className={s.circle}>{row.progress || 0}%</span>
												</>
											)}
										</div>
									);
								},
							},
							...(chooseTaskTriggerType !== 'schedule'
								? []
								: [
										{
											title: '下次检测时间',
											key: 'next_time',
											dataIndex: 'next_time',
											render(e, row) {
												return (
													<span>
														{(e && moment(e).format('YYYY-MM-DD HH:mm:ss')) ||
															'- -'}
													</span>
												);
											},
										},
								  ]),
						]}
						data={progressData}
						pro
						loading={loading}
						empty={<EmptyData className={s.nobor} />}
					/>
				</div>
			</Dialog>
		</div>
	);
}

TaskTable.propTypes = {
	match: PropTypes.any,
	location: PropTypes.any,
	history: PropTypes.any,
};
TaskTable.defaultProps = {
	className: '',
};

export default withRouter(TaskTable);
